package com.mimiwang.chat.controller;

import com.alibaba.fastjson.JSONObject;
import com.mimiwang.chat.config.EndPointConfigurator;
import com.mimiwang.chat.entity.Talk;
import com.mimiwang.chat.service.ChatTalkRedisService;
import com.mimiwang.chat.service.ChatTalkService;
import com.mimiwang.common.utils.ResponseUtil;
import com.mimiwang.common.utils.TokenUtil;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RestController;

import javax.websocket.*;
import javax.websocket.server.ServerEndpoint;
import java.sql.Timestamp;
import java.util.Date;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

/**
 * @AUTHOR:游李滨
 * @DATE:2023/4/18 13:39
 */

@RestController
@ServerEndpoint(value = "/ws",configurator = EndPointConfigurator.class)
@Data
@Slf4j
public class ChatWSController {


    public static ChatTalkService chatTalkService;
    public static ChatTalkRedisService redisService;





    public static void main(String[] args) {
        String token = TokenUtil.generateToken(2);
        System.out.println(token);
    }
    // concurrent包的线程安全Set，用来存放每个客户端对应的MyWebSocket对象
    private static final Map<Long, ChatWSController> webSocketMap = new ConcurrentHashMap();

    // 与某个客户端的连接会话，需要通过它来与客户端进行数据收发
    private Session session;
    private long userId;



    @Autowired
    public void setService (ChatTalkService chatTalkService,ChatTalkRedisService redisService){
        ChatWSController.chatTalkService=chatTalkService;
        ChatWSController.redisService=redisService;
    }

    /**
     * 打开连接
     *
     * @param session 会话
     * @throws Exception 异常
     */

    @OnOpen
    public void onOpen(Session session, EndpointConfig endpointConfig) {
        log.error("open");
        this.session = session;
        String id = (String) endpointConfig.getUserProperties().get("id");
        long userId = Long.parseLong(id);
        this.userId=userId;
        webSocketMap.put(userId,this);
        log.error("{} 上线了",userId);

    }
    /**
     * 关闭连接
     */
    @OnClose
    public void onClose(Session session, CloseReason closeReason) {
        log.error("{} 离线了",this.userId);
        webSocketMap.remove(this.userId);
    }


    Talk generateTalk(String message){
        //        string 转 obj
        Talk talk = JSONObject.parseObject(message, Talk.class);
        talk.setCreateTime(new Timestamp(new Date().getTime()));
        talk.setRead(1);
        talk.setSender(this.userId);
        talk.setReceiverType(1);
        talk.setType(1);
        return talk;
    }
    @OnMessage
    public void onMessage(String message, Session session) throws Exception {
        log.error("消息{}",message);

        Talk talk = this.generateTalk(message);
        System.out.println("talk: "+talk);
        //        找到接收者
        long receiverId = talk.getReceiver();
        if(receiverId <1){
           this.sendErrorMessage("请选择发送用户");
           return;
        }

        // TODO 聊天记录存入数据库
        try {
            int i = chatTalkService.insertOne(talk);
            if(i == 0){
                log.error("新增聊天记录错误!");
                this.sendErrorMessage("网络错误!请稍后重试!");
                return;
            }
        }catch (Exception e){
            e.printStackTrace();
        }



        ChatWSController chatWSController = webSocketMap.get(receiverId);
        if(chatWSController !=null){
//           被发送消息打用户在线，直接发送
            Session receiver = chatWSController.getSession();
            this.sendSuccessMessage(talk,receiver);
        }else{
            log.error("{} 离线，暂时不发送",receiverId);
        }


    }



    /**
     * 报错
     *
     * @param session 会话
     * @param error   错误
     */
    @OnError
    public void onError(Session session, Throwable error) {
        log.error("Chat Error!Reason:{}",error.getMessage());
    }


    public void sendErrorMessage(String str) throws Exception {

        String result = ResponseUtil.errorJSONData(str);
        this.session.getBasicRemote().sendText(result);

    }
    /**
     * 发送消息
     *
     * @param talk 会话
     * @throws Exception 异常
     */
    public void sendSuccessMessage(Talk talk,Session session) throws Exception {

        String result = ResponseUtil.successJSONData(talk);
        session.getBasicRemote().sendText(result);

    }
    public void sendMessage(String message,Session session) throws Exception {

        session.getBasicRemote().sendText(message);

    }
    /**
     * 获取在线连接数
     *
     * @return onlineCount
     */
    public static synchronized int getOnlineCount() {
        return webSocketMap.size();
    }


}
